package com.hcc.export.helper.core.repository.impl;

import com.hcc.export.helper.core.domain.po.ExportConfig;
import com.hcc.export.helper.core.domain.po.ExportTaskRecord;
import com.hcc.export.helper.core.repository.ExportRepo;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository("exportHelperExportRepo")
public class ExportRepoImpl implements ExportRepo {

    private final JdbcTemplate jdbcTemplate;
    private final NamedParameterJdbcTemplate namedParamJdbcTemplate;

    public ExportRepoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        this.namedParamJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
    }

    @Override
    public void insertExportConfig(ExportConfig exportConfig) {
        String sql = "INSERT INTO export_config (export_code, export_name, export_bean_name, export_bean_class_name, export_method_name, export_param_class_name, export_result_class_name, max_retry_count, create_time, update_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, now(), now())";
        jdbcTemplate.update(sql, exportConfig.getExportCode(), exportConfig.getExportName(), exportConfig.getExportBeanName(),
                exportConfig.getExportBeanClassName(), exportConfig.getExportMethodName(), exportConfig.getExportParamClassName(),
                exportConfig.getExportResultClassName(), exportConfig.getMaxRetryCount());
    }

    @Override
    public ExportConfig getExportConfigByExportCode(String exportCode) {
        String sql = "SELECT * FROM export_config c WHERE c.export_code = ? LIMIT 1";

        List<ExportConfig> results = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ExportConfig.class), exportCode);
        if (results.isEmpty()) {
            return null;
        }

        return results.get(0);
    }

    @Override
    public Long insertExportTaskRecord(ExportTaskRecord exportTaskRecord) {
        String sql = "INSERT INTO export_task_record (export_config_id, export_code, export_param_json, file_name, export_status, retry_count, export_user_id, export_user_name, create_time, update_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, now(), now())";

        KeyHolder keyHolder = new GeneratedKeyHolder();

        jdbcTemplate.update(conn -> {
            PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            ps.setLong(1, exportTaskRecord.getExportConfigId());
            ps.setString(2, exportTaskRecord.getExportCode());
            ps.setString(3, exportTaskRecord.getExportParamJson());
            ps.setString(4, exportTaskRecord.getFileName());
            ps.setString(5, exportTaskRecord.getExportStatus());
            ps.setInt(6, exportTaskRecord.getRetryCount());
            ps.setLong(7, exportTaskRecord.getExportUserId());
            ps.setString(8, exportTaskRecord.getExportUserName());

            return ps;
        }, keyHolder);

        return keyHolder.getKey() != null ? keyHolder.getKey().longValue() : null;
    }

    @Override
    public ExportTaskRecord getExportTaskRecordById(Long id) {
        String sql = "SELECT * FROM export_task_record r WHERE r.id = ? LIMIT 1";

        List<ExportTaskRecord> results = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ExportTaskRecord.class), id);
        if (results.isEmpty()) {
            return null;
        }

        return results.get(0);
    }

    @Override
    public void updateExportTaskRecord(ExportTaskRecord exportTaskRecord) {
        Map<String, Object> paramMap = new HashMap<>();
        StringBuilder sql = new StringBuilder("UPDATE export_task_record r SET r.update_time = now(), r.retry_count = r.retry_count + 1");
        if (exportTaskRecord.getFileUrl() != null) {
            sql.append(", r.file_url = :fileUrl");
            paramMap.put("fileUrl", exportTaskRecord.getFileUrl());
        }
        if (exportTaskRecord.getCost() != null) {
            sql.append(", r.cost = :cost");
            paramMap.put("cost", exportTaskRecord.getCost());
        }
        if (exportTaskRecord.getExportStatus() != null) {
            sql.append(", r.export_status = :exportStatus");
            paramMap.put("exportStatus", exportTaskRecord.getExportStatus());
        }
        if (exportTaskRecord.getFailedReason() != null) {
            sql.append(", r.failed_reason = :failedReason");
            paramMap.put("failedReason", exportTaskRecord.getFailedReason());
        }
        sql.append(" WHERE r.id = :id");
        paramMap.put("id", exportTaskRecord.getId());

        namedParamJdbcTemplate.update(sql.toString(), paramMap);
    }

}
